const fs = require('fs')
const path = require('path')
const JavaScriptObfuscator = require('javascript-obfuscator')

/**
 * 密钥相关文件混淆工具
 * 用于在打包前对关键文件进行混淆处理
 */
class KeyObfuscator {
  constructor() {
    this.obfuscationOptions = {
      compact: true,
      controlFlowFlattening: true,
      controlFlowFlatteningThreshold: 0.8,
      deadCodeInjection: true,
      deadCodeInjectionThreshold: 0.4,
      debugProtection: true,
      debugProtectionInterval: 2000,
      disableConsoleOutput: false, // 保留console输出用于调试
      identifierNamesGenerator: 'hexadecimal',
      log: false,
      numbersToExpressions: true,
      renameGlobals: false,
      selfDefending: true,
      simplify: true,
      splitStrings: true,
      splitStringsChunkLength: 5,
      stringArray: true,
      stringArrayCallsTransform: true,
      stringArrayEncoding: ['base64'],
      stringArrayIndexShift: true,
      stringArrayRotate: true,
      stringArrayShuffle: true,
      stringArrayWrappersCount: 2,
      stringArrayWrappersChainedCalls: true,
      stringArrayWrappersParametersMaxCount: 4,
      stringArrayWrappersType: 'function',
      stringArrayThreshold: 0.8,
      transformObjectKeys: true,
      unicodeEscapeSequence: false
    }
  }

  /**
   * 混淆单个文件
   */
  obfuscateFile(inputPath, outputPath = null) {
    if (!fs.existsSync(inputPath)) {
      throw new Error(`输入文件不存在: ${inputPath}`)
    }

    const sourceCode = fs.readFileSync(inputPath, 'utf8')
    const obfuscatedResult = JavaScriptObfuscator.obfuscate(sourceCode, this.obfuscationOptions)
    
    const finalOutputPath = outputPath || inputPath.replace('.js', '.obfuscated.js')
    fs.writeFileSync(finalOutputPath, obfuscatedResult.getObfuscatedCode())
    
    console.log(`文件混淆完成: ${inputPath} -> ${finalOutputPath}`)
    return finalOutputPath
  }

  /**
   * 混淆密钥管理器文件
   */
  obfuscateKeyManager(basePath = null) {
    const projectRoot = basePath || path.join(__dirname, '..', '..')
    const keyManagerPath = path.join(projectRoot, 'src', 'main', 'key-manager.js')
    
    if (!fs.existsSync(keyManagerPath)) {
      throw new Error(`密钥管理器文件不存在: ${keyManagerPath}`)
    }

    const obfuscatedPath = this.obfuscateFile(keyManagerPath)
    
    // 创建一个替换原文件的脚本
    const originalBackupPath = keyManagerPath + '.original'
    if (!fs.existsSync(originalBackupPath)) {
      fs.copyFileSync(keyManagerPath, originalBackupPath)
      console.log(`原文件已备份: ${originalBackupPath}`)
    }
    
    return {
      obfuscatedPath,
      originalPath: keyManagerPath,
      backupPath: originalBackupPath
    }
  }

  /**
   * 还原混淆文件（用于开发环境）
   */
  restoreKeyManager(basePath = null) {
    const projectRoot = basePath || path.join(__dirname, '..', '..')
    const keyManagerPath = path.join(projectRoot, 'src', 'main', 'key-manager.js')
    const backupPath = keyManagerPath + '.original'
    
    if (fs.existsSync(backupPath)) {
      fs.copyFileSync(backupPath, keyManagerPath)
      console.log(`已还原原始文件: ${keyManagerPath}`)
      
      // 删除混淆文件和备份文件
      const obfuscatedPath = keyManagerPath.replace('.js', '.obfuscated.js')
      if (fs.existsSync(obfuscatedPath)) {
        fs.unlinkSync(obfuscatedPath)
      }
      fs.unlinkSync(backupPath)
      
      return true
    } else {
      console.warn('未找到备份文件，无法还原')
      return false
    }
  }

  /**
   * 应用混淆到构建环境
   */
  applyObfuscationForBuild(basePath = null) {
    try {
      const result = this.obfuscateKeyManager(basePath)
      
      // 用混淆后的文件替换原文件
      fs.copyFileSync(result.obfuscatedPath, result.originalPath)
      console.log('混淆文件已应用到构建环境')
      
      // 清理临时混淆文件
      fs.unlinkSync(result.obfuscatedPath)
      
      return true
    } catch (error) {
      console.error('应用混淆失败:', error.message)
      return false
    }
  }

  /**
   * 创建用于运行时的额外保护层
   */
  createRuntimeProtection() {
    const protectionCode = `
// 运行时保护代码
(function() {
  'use strict';
  
  // 检测调试器
  let devtools = {
    open: false,
    orientation: null
  };
  
  const threshold = 160;
  
  setInterval(function() {
    if (window.outerHeight - window.innerHeight > threshold || 
        window.outerWidth - window.innerWidth > threshold) {
      if (!devtools.open) {
        devtools.open = true;
        console.warn('Developer tools detected');
        // 可以在这里添加更多保护措施
      }
    } else {
      devtools.open = false;
    }
  }, 500);
  
  // 禁用右键菜单（可选）
  // document.addEventListener('contextmenu', e => e.preventDefault());
  
  // 禁用常见调试快捷键（可选）
  document.addEventListener('keydown', function(e) {
    if (e.key === 'F12' || 
        (e.ctrlKey && e.shiftKey && e.key === 'I') ||
        (e.ctrlKey && e.shiftKey && e.key === 'C') ||
        (e.ctrlKey && e.shiftKey && e.key === 'J')) {
      e.preventDefault();
    }
  });
})();
    `
    
    return protectionCode.trim()
  }
}

module.exports = KeyObfuscator